package com.css.listener;

import com.css.entity.KeyMapWrapper;
import com.css.listener.interfaces.KeyBorderListener;
import com.sun.jna.platform.win32.Kernel32;
import com.sun.jna.platform.win32.User32;
import com.sun.jna.platform.win32.WinDef;
import com.sun.jna.platform.win32.WinUser;


/**
 * <p>
 * - 键盘监听
 * </p>
 *
 * @author css
 * @since 2019/1/9
 */
public class KeyBoarder {
    private static WinUser.LowLevelKeyboardProc keyboardHook;
    static WinDef.HMODULE hMod = Kernel32.INSTANCE.GetModuleHandle(null);
    static WinUser.HHOOK hhook;
    final static User32 lib = User32.INSTANCE;
    private KeyBorderListener borderListener;

    public KeyBoarder() {
        init();
    }

    private void init() {
        new Thread(() -> {

            keyboardHook = (nCode, wParam, info) -> {
                int action = wParam.intValue();
                switch (action) {
                    case 256:
                    case 260:
                        if (borderListener != null) {
                            if (KeyMapWrapper.put(info.vkCode)) {
                                borderListener.onDown(info.vkCode);
                            }
                            borderListener.onPress(info.vkCode);
                        }
                        break;
                    case 257:
                        if (borderListener != null) {
                            borderListener.onUp(info.vkCode);
                        }
                        break;
                }
                WinDef.LPARAM lparam = new WinDef.LPARAM();
                return lib.CallNextHookEx(hhook, nCode, wParam, lparam);
            };
            hhook = lib.SetWindowsHookEx(User32.WH_KEYBOARD_LL, keyboardHook, hMod, 0);
            int result;
            WinUser.MSG msg = new WinUser.MSG();
            while ((result = lib.GetMessage(msg, null, 0, 0)) != 0) {
                if (result == -1) {
                    System.err.println("error in get message");
                    break;
                } else {
                    System.err.println("got message");
                    lib.TranslateMessage(msg);
                    lib.DispatchMessage(msg);
                }
            }
            lib.UnhookWindowsHookEx(hhook);
        }).start();
    }


    public void setBorderListener(KeyBorderListener borderListener) {
        this.borderListener = borderListener;
    }
}
